package com.swills.mandelbrot;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class MyFrame extends JFrame {

	private static final String POPULATION = "POPULATION";

	private static final String MANDELBROT = "MANDELBROT";

	private static final int MAX_ITERATIONS = 4000;

	private static final int MIN_ITERATIONS = 30;

	private static final String ITERATIONS_TEXT = "Iterations = ";

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private final JRadioButton mandlebrotRB;
	private final JRadioButton populationRB;
	private final ButtonGroup choiceGp;
	private final JCheckBox showAxisChk;
	private final JButton closeBtn;
	private final JButton resetBtn;
	private final JSlider iterationSlider;
	private final JLabel iterationLbl;
	private final JPanel base;
	private final MyCanvas canvas;
	private final Population population;
	private static Variables vars;

	public static Variables getVars() {
		if (vars == null) {
			vars = new Variables();
		}
		return vars;
	}

	/**
	 * Constructor
	 */
	public MyFrame() {
		getVars().setMaxIterations(MIN_ITERATIONS);
		Container container = this.getContentPane();
		mandlebrotRB = new JRadioButton("Mandlebrot");
		populationRB = new JRadioButton("Population");
		choiceGp = new ButtonGroup();
		choiceGp.add(mandlebrotRB);
		choiceGp.add(populationRB);

		showAxisChk = new JCheckBox("Show Axis");
		closeBtn = new JButton("Close");
		resetBtn = new JButton("Reset");
		iterationSlider = new JSlider(JSlider.HORIZONTAL, MIN_ITERATIONS,
				MAX_ITERATIONS, MIN_ITERATIONS);
		iterationLbl = new JLabel(ITERATIONS_TEXT + iterationSlider.getValue());
		base = new JPanel();
		canvas = new MyCanvas();
		population = new Population();
		base.add(mandlebrotRB);
		base.add(populationRB);
		base.add(closeBtn);
		base.add(showAxisChk);
		base.add(resetBtn);
		base.add(iterationSlider);
		base.add(iterationLbl);

		container.add(base, BorderLayout.PAGE_START);
		container.add(canvas, BorderLayout.CENTER);
		// container.add(population, BorderLayout.CENTER);

		base.setBackground(Color.BLUE);
		this.setTitle("Mandelbrot Set");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.pack();

		wire();
	}

	private void wire() {
		populationRB.setSelected(true);
		// showMandelbrot(false);
		showAxisChk.setBackground(Color.BLUE);

		ActionListener choiceListener = new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				showMandelbrot(e.getActionCommand().equals(MANDELBROT));
			}
		};
		mandlebrotRB.setActionCommand(MANDELBROT);
		mandlebrotRB.setSelected(true);
		mandlebrotRB.setBackground(Color.BLUE);
		mandlebrotRB.addActionListener(choiceListener);

		populationRB.setActionCommand(POPULATION);
		populationRB.setBackground(Color.BLUE);
		populationRB.addActionListener(choiceListener);

		closeBtn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});

		showAxisChk.addItemListener(new ItemListener() {

			@Override
			public void itemStateChanged(ItemEvent e) {
				vars.setShowAxis(e.getStateChange() == ItemEvent.SELECTED);
				canvas.repaint();
			}
		});

		resetBtn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				if (mandlebrotRB.isSelected()) {
					resetMandelbrot();
				} else {
					resetPopulation();
				}
			}

			private void resetPopulation() {
				population.resetPopulation();
			}

			private void resetMandelbrot() {
				canvas.init();
				canvas.setDoPaint(true);
				canvas.repaint();
			}
		});

		iterationSlider.addChangeListener(new ChangeListener() {

			@Override
			public void stateChanged(ChangeEvent e) {
				JSlider source = (JSlider) e.getSource();
				iterationLbl.setText(ITERATIONS_TEXT + source.getValue());
				if (!source.getValueIsAdjusting()) {
					vars.setMaxIterations(source.getValue());
					canvas.repaint();
				}
			}
		});

	}

	private void showMandelbrot(boolean show) {
		if (!show) {
			getContentPane().remove(canvas);
			getContentPane().add(population, BorderLayout.CENTER);
		} else {
			getContentPane().remove(population);
			getContentPane().add(canvas, BorderLayout.CENTER);
		}
		canvas.setVisible(show);
		population.setVisible(!show);
		showAxisChk.setVisible(show);
		iterationSlider.setVisible(show);
		iterationLbl.setVisible(show);

		getContentPane().invalidate();
	}

	/**
	 * Create and show the frame.
	 * 
	 */
	public static void main(String[] args) {
		MyFrame myFrame = new MyFrame();
		myFrame.setExtendedState(myFrame.getExtendedState() | MAXIMIZED_BOTH);
		myFrame.setVisible(true);
	}

}
